//go:build wireinject

package startup

import (
	"github.com/gin-gonic/gin"
	"github.com/google/wire"
	repository2 "webook/interactive/repository"
	cache2 "webook/interactive/repository/cache"
	dao2 "webook/interactive/repository/dao"
	service2 "webook/interactive/service"
	"webook/internal/events/article"
	"webook/internal/repository"
	"webook/internal/repository/cache"
	"webook/internal/repository/dao"
	"webook/internal/service"
	"webook/internal/web"
	ijwt "webook/internal/web/jwt"
	"webook/ioc"
)

var thirdPartySet = wire.NewSet(
	//第三方依赖
	InitRedis, InitDB, InitLog,
	InitSaramaClient,
	InitSyncProducer,
)
var interactiveSvcSet = wire.NewSet(dao2.NewGORMInteractiveDao, cache2.NewRedisInteractiveCache,
	repository2.NewCachedInteractiveRepository, service2.NewInteractiveService)
var userSvcProvider = wire.NewSet(
	dao.NewUserDAO,
	cache.NewUserCache,
	repository.NewCacheUserRepository,
	service.NewUserService)
var articlSvcProvider = wire.NewSet(
	repository.NewCacheArticleRepository,
	cache.NewArticleRedisCache,
	dao.NewArticleORMDAO,
	service.NewArticleService)

func InitWebServer() *gin.Engine {
	wire.Build(
		thirdPartySet,
		//dao
		dao.NewUserDAO,
		//self_cache
		cache.NewUserCache, cache.NewCodeCache,
		//repository
		repository.NewCacheUserRepository, repository.NewCodeRepository,
		article.NewSaramaSyncProducer,
		//service
		ioc.InitSMSService, ioc.InitWechatService,
		service.NewUserService, service.NewCodeService,
		//handler
		ijwt.NewRedisJWTHandler,
		web.NewUserHandler,
		web.NewOAuth2WechatHandler,
		web.NewArticleHandler,
		ioc.InitGinMiddlewares, ioc.InitWebServer,
		interactiveSvcSet,
		articlSvcProvider,
	)
	return gin.Default()
}
func InitArticleHandler(dao dao.ArticleDao) *web.ArticleHandler {
	wire.Build(
		thirdPartySet,
		//dao.NewArticleORMDAO,
		service.NewArticleService,
		repository.NewCacheArticleRepository,
		cache.NewArticleRedisCache,
		web.NewArticleHandler,
		article.NewSaramaSyncProducer,
		interactiveSvcSet,
		userSvcProvider,
	)
	return &web.ArticleHandler{}
}
func InitInteractiveService() service2.InteractiveService {
	wire.Build(thirdPartySet, interactiveSvcSet)
	return service2.NewInteractiveService(nil)
}
